import secrets
from datetime import timedelta
from flask import Flask, request, jsonify, session, redirect, url_for
from backend.extensions import db  # 从 extensions 导入 db
# 顶部导入
from flask_migrate import Migrate
from flask_cors import CORS
from backend.config import Config
# 导入模型（必须在 db 和 migrate 之后）
from backend.models import User, Role, Menu, ModelProvider, user_roles, role_menus, Provider, ProviderModel, UserDefaultModel, ProviderModelSetting
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import LoginManager, UserMixin, login_user, logout_user, current_user,login_required, AnonymousUserMixin
from backend.ollama.ollama_client import OllamaClient
# 初始化 Flask 应用
app = Flask(__name__)
# 加载配置（确保 config.py 在 backbend 目录下）
app.config.from_object(Config)  # 显式路径
# 生成一个 16 字节的十六进制字符串作为 SECRET_KEY
secret_key = secrets.token_hex(16)
app.config['SECRET_KEY'] = secret_key  # 用于加密会话
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=30)  # 会话过期时间

# 初始化数据库
db.init_app(app)
# 初始化迁移工具
migrate = Migrate(app, db)
# 初始化 LoginManager
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
CORS(app, origins=["http://localhost:5173"])

@app.route('/register', methods=['POST'])
def register():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    if not username or not password:
        return jsonify({"message": "Username and password are required"}), 400

    if User.query.filter_by(username=username).first():
        return jsonify({"message": "Username already exists"}), 400

    hashed_password = generate_password_hash(password)
    # print(f"Hashed password: {hashed_password}")  # 添加这行用于调试
    new_user = User(username=username, password=hashed_password, password_hash=hashed_password)
    db.session.add(new_user)
    db.session.commit()

    return jsonify({"message": "User registered successfully"}), 201

@app.route('/login', methods=['POST'])
def login():
    # 从请求中获取 JSON 数据
    data = request.get_json()
    # 从 JSON 数据中提取用户名
    username = data.get('username')
    # 从 JSON 数据中提取密码
    password = data.get('password')

    # 在数据库中查询与输入用户名匹配的第一个用户记录
    user = User.query.filter_by(username=username).first()

    # 如果找到了匹配的用户记录
    if user:
        #检查输入的密码是否与数据库中存储的哈希密码匹配
        password_match = check_password_hash(user.password, password)
        # 打印密码匹配结果，用于调试
        print(f"Password match: {password_match}")
        # 如果密码匹配
        if password_match:
            # 使用 Flask-Login 登录用户
            login_user(user)
            # 获取当前用户的角色列表
            roles = [role.name for role in user.roles]
            if 'ordinary_employee' in roles:
                # 如果用户具有普通员工角色，则重定向到普通员工页面
                return jsonify({"message": "登录成功", "redirect": url_for('get_ordinary_employee')}), 200
            elif 'finance_approver' in roles:
                # 如果用户具有财务审核员角色，则重定向到财务审核页面
                return jsonify({"message": "登录成功", "redirect": url_for('get_finance_approver')}), 200
            else:
                # 返回登录成功的 JSON 响应，状态码为 200
                return jsonify({"message": "登录成功", "redirect": url_for('get_system_manager')}), 200
        else:
            # 如果密码不匹配，返回错误消息，状态码为 401
            return jsonify({"message": "Invalid username or password"}), 401
        # return jsonify({"message": "登陆成功"}), 200
    else:
        # 如果没有找到匹配的用户记录，返回错误消息，状态码为 401
        return jsonify({"message": "Invalid username or password"}), 401

@app.route('/ordinary-employee')
def get_ordinary_employee():
    # 返回普通员工页面的数据或渲染页面
    return jsonify({"message": "This is ordinary employee page"})
@app.route('/finance-approver')
def get_finance_approver():
    # 返回财务审核页面的数据或渲染页面
    return jsonify({"message": "This is finance approver page"})
@app.route('/system-manager')
def get_system_manager():
    # 返回系统管理员页面的数据或渲染页面
    return jsonify({"message": "This is system manager page"})
@app.route('/logout', methods=['POST'])
def logout():
    logout_user()
    return jsonify({"message": "Logged out successfully"}), 200


# 用户管理
@app.route('/users', methods=['GET'])
# @login_required
def get_users():
    users = User.query.all()
    return jsonify([{
        'id': user.id,
        'username': user.username,
        'roles': [role.name for role in user.roles]
    } for user in users]), 200


@app.route('/users', methods=['POST'])
# @login_required
def create_user():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')
    role_ids = data.get('role_ids', [])

    if User.query.filter_by(username=username).first():
        return jsonify({"message": "Username already exists"}), 400

    new_user = User(username=username)
    new_user.set_password(password)

    if role_ids:
        new_user.roles = Role.query.filter(Role.id.in_(role_ids)).all()

    db.session.add(new_user)
    db.session.commit()

    return jsonify({
        'message': "User created successfully",
        'user': {
            'id': new_user.id,
            'username': new_user.username,
            'roles': [role.name for role in new_user.roles]
        }
    }), 201


# 角色管理
@app.route('/roles', methods=['GET'])
# @login_required
def get_roles():
    roles = Role.query.all()
    return jsonify([{
        'id': role.id,
        'name': role.name,
        'menus': [menu.route for menu in role.menus]
    } for role in roles]), 200


@app.route('/roles', methods=['POST'])
# @login_required
def create_role():

    data = request.get_json()
    name = data.get('name')
    menu_ids = data.get('menu_ids', [])

    if Role.query.filter_by(name=name).first():
        return jsonify({"message": "Role already exists"}), 400

    new_role = Role(name=name)

    if menu_ids:
        new_role.menus = Menu.query.filter(Menu.id.in_(menu_ids)).all()

    db.session.add(new_role)
    db.session.commit()

    return jsonify({
        'message': "Role created successfully",
        'role': {
            'id': new_role.id,
            'name': new_role.name,
            'menus': [menu.route for menu in new_role.menus]
        }
    }), 201


# 菜单管理
@app.route('/menus', methods=['GET'])
# @login_required
def get_menus():

    menus = Menu.query.order_by(Menu.order).all()

    def build_tree(menus, parent_id=None):
        tree = []
        for menu in menus:
            if menu.parent_id == parent_id:
                tree.append({
                    'id': menu.id,
                    'name': menu.name,
                    'route': menu.route,
                    'icon': menu.icon,
                    'children': build_tree(menus, menu.id)
                })
        return tree

    return jsonify(build_tree(menus)), 200


@app.route('/menus', methods=['POST'])
# @login_required
def create_menu():
    data = request.get_json()
    name = data.get('name')
    route = data.get('route')
    icon = data.get('icon', '')
    parent_id = data.get('parent_id')
    order = data.get('order', 0)

    if Menu.query.filter_by(route=route).first():
        return jsonify({"message": "Route already exists"}), 400

    new_menu = Menu(
        name=name,
        route=route,
        icon=icon,
        parent_id=parent_id,
        order=order
    )

    db.session.add(new_menu)
    db.session.commit()

    return jsonify({
        'message': "Menu created successfully",
        'menu': {
            'id': new_menu.id,
            'name': new_menu.name,
            'route': new_menu.route,
            'icon': new_menu.icon,
            'parent_id': new_menu.parent_id,
            'order': new_menu.order
        }
    }), 201

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

# 文本单次生成
@app.route('/api/models/generate', methods=['POST'])
# text_response = ollama.generate(
#         model_name="qwen2.5:3b",
#         prompt="请用中文解释人工智能的基本概念",
#         parameters={
#             "temperature": 0.7,
#             "max_tokens": 500
#         }
#     )
def model_generate():
    data = request.get_json()
    model_name = data.get('model_name', 'deepseek-r1:latest')
    prompt = data.get('prompt')
    client = OllamaClient()
    text_response = client.generate(model_name, prompt,  parameters={
            "temperature": 0.7,
            "max_tokens": 500
        })
    return jsonify({"生成": text_response})


# 包含历史生成
@app.route('/api/models/chat', methods=['POST'])
#  chat_history = [
#         {"role": "user", "content": "你好，请介绍一下你自己"},
#         {"role": "assistant", "content": "我是由Ollama驱动的AI助手，我可以帮助回答各种问题。"},
#         {"role": "user", "content": "你能用中文进行对话吗？"}
#     ]
#
#     chat_response = ollama.chat(
#         model_name="deepseek-r1:latest",
#         messages=chat_history,
#         parameters={
#             "temperature": 0.9,
#             "max_tokens": 300
#         }
#     )
def model_chat():
    data = request.get_json()
    model_name = data.get('model_name', 'deepseek-r1:latest')
    chat_history = data.get('chat_history')
    client = OllamaClient()
    chat_response = client.chat(model_name, messages=chat_history,  parameters={
            "temperature": 0.7,
            "max_tokens": 500
        })
    return jsonify({"生成": chat_response})
# 用户菜单接口
@app.route('/api/user-menu', methods=['GET'])
@login_required
def get_user_menu():
    if isinstance(current_user, AnonymousUserMixin):
        return jsonify({"error": "用户未登录"}), 401

    # 获取当前登录用户的角色
    user_roles = current_user.roles
    # 存储所有角色下的菜单
    all_menus = []
    for role in user_roles:
        # 获取每个角色下的菜单
        role_menus = role.menus
        all_menus.extend(role_menus)
    # 去重
    unique_menus = list(set(all_menus))
    # 按 order 字段排序
    unique_menus.sort(key=lambda x: x.order)

    def build_tree(menus, parent_id=None):
        tree = []
        for menu in menus:
            if menu.parent_id == parent_id:
                tree.append({
                    'id': menu.id,
                    'name': menu.name,
                    'route': menu.route,
                    'icon': menu.icon,
                    'children': build_tree(menus, menu.id)
                })
        return tree

    return jsonify(build_tree(unique_menus)), 200


# ---------- Provider 模型的增删改查接口 ----------
@app.route('/providers', methods=['GET'])
# @login_required
def get_providers():
    """获取所有 Provider（列表查）"""
    providers = Provider.query.all()
    return jsonify([{
        'id': p.id,
        'user_id': p.user_id,
        'provider_name': p.provider_name,
        'provider_type': p.provider_type,
        'quota_type': p.quota_type,
        'quota_limit': p.quota_limit,
        'quota_used': p.quota_used,
        'is_valid': p.is_valid
    } for p in providers]), 200


@app.route('/providers/<int:provider_id>', methods=['GET'])
# @login_required
def get_provider(provider_id):
    """获取单个 Provider 详情"""
    provider = Provider.query.get(provider_id)
    if not provider:
        return jsonify({"message": "Provider not found"}), 404
    return jsonify({
        'id': provider.id,
        'user_id': provider.user_id,
        'provider_name': provider.provider_name,
        'provider_type': provider.provider_type,
        'quota_type': provider.quota_type,
        'quota_limit': provider.quota_limit,
        'quota_used': provider.quota_used,
        'is_valid': provider.is_valid,
        'created_at': provider.created_at.isoformat(),
        'updated_at': provider.updated_at.isoformat()
    }), 200


@app.route('/providers', methods=['POST'])
# @login_required
def create_provider():
    """创建 Provider"""
    data = request.get_json()
    # 必填字段验证
    required_fields = ['provider_name', 'provider_type']
    for field in required_fields:
        if not data.get(field):
            return jsonify({"message": f"Missing required field: {field}"}), 400

    # 创建记录
    new_provider = Provider(
        user_id=1,
        provider_name=data['provider_name'],
        provider_type=data['provider_type'],
        quota_type=data.get('quota_type'),
        quota_limit=data.get('quota_limit'),
        is_valid=data.get('is_valid', False)
    )
    db.session.add(new_provider)
    db.session.commit()
    return jsonify({"message": "Provider created", "id": new_provider.id}), 201


@app.route('/providers/<int:provider_id>', methods=['PUT'])
# @login_required
def update_provider(provider_id):
    """更新 Provider"""
    provider = Provider.query.get(provider_id)
    if not provider:
        return jsonify({"message": "Provider not found"}), 404

    data = request.get_json()
    # 更新字段（根据实际需求调整可更新字段）
    updatable_fields = ['provider_name', 'provider_type', 'quota_type', 'quota_limit', 'is_valid']
    for field in updatable_fields:
        if field in data:
            setattr(provider, field, data[field])

    db.session.commit()
    return jsonify({"message": "Provider updated"}), 200


@app.route('/providers/<int:provider_id>', methods=['DELETE'])
# @login_required
def delete_provider(provider_id):
    """删除单个 Provider"""
    provider = Provider.query.get(provider_id)
    if not provider:
        return jsonify({"message": "Provider not found"}), 404

    db.session.delete(provider)
    db.session.commit()
    return jsonify({"message": "Provider deleted"}), 200


@app.route('/providers/batch-delete', methods=['POST'])
# @login_required
def batch_delete_providers():
    """批量删除 Providers"""
    data = request.get_json()
    ids = data.get('ids', [])
    if not ids:
        return jsonify({"message": "No IDs provided"}), 400

    # 批量删除操作
    try:
        Provider.query.filter(Provider.id.in_(ids)).delete(synchronize_session=False)
        db.session.commit()
        return jsonify({"message": f"Deleted {len(ids)} providers"}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({"message": "Batch delete failed", "error": str(e)}), 500


# ---------- ProviderModel 模型的完整 CRUD 接口 ----------
@app.route('/provider-models/<int:model_id>', methods=['GET'])
# @login_required
def get_provider_model(model_id):
    """获取单个 ProviderModel 详情"""
    model = ProviderModel.query.get(model_id)
    if not model:
        return jsonify({"message": "Provider model not found"}), 404
    return jsonify({
        'id': model.id,
        'user_id': model.user_id,
        'provider_name': model.provider_name,
        'model_name': model.model_name,
        'model_type': model.model_type,
        'is_valid': model.is_valid,
        'created_at': model.created_at.isoformat(),
        'updated_at': model.updated_at.isoformat()
    }), 200

@app.route('/provider-models', methods=['POST'])
# @login_required
def create_provider_model():
    """创建 ProviderModel"""
    data = request.get_json()
    # 必填字段验证
    required_fields = ['provider_name', 'model_name', 'model_type']
    for field in required_fields:
        if not data.get(field):
            return jsonify({"message": f"Missing required field: {field}"}), 400

    # 创建记录
    new_model = ProviderModel(
        user_id=current_user.id,
        provider_name=data['provider_name'],
        model_name=data['model_name'],
        model_type=data['model_type'],
        encrypted_config=data.get('encrypted_config'),
        is_valid=data.get('is_valid', False)
    )
    db.session.add(new_model)
    db.session.commit()
    return jsonify({"message": "Provider model created", "id": new_model.id}), 201

@app.route('/provider-models/<int:model_id>', methods=['PUT'])
# @login_required
def update_provider_model(model_id):
    """更新 ProviderModel"""
    model = ProviderModel.query.get(model_id)
    if not model:
        return jsonify({"message": "Provider model not found"}), 404

    data = request.get_json()
    # 更新字段
    updatable_fields = ['provider_name', 'model_name', 'model_type', 'encrypted_config', 'is_valid']
    for field in updatable_fields:
        if field in data:
            setattr(model, field, data[field])

    db.session.commit()
    return jsonify({"message": "Provider model updated"}), 200

@app.route('/provider-models/<int:model_id>', methods=['DELETE'])
# @login_required
def delete_provider_model(model_id):
    """删除单个 ProviderModel"""
    model = ProviderModel.query.get(model_id)
    if not model:
        return jsonify({"message": "Provider model not found"}), 404

    db.session.delete(model)
    db.session.commit()
    return jsonify({"message": "Provider model deleted"}), 200

@app.route('/provider-models/batch-delete', methods=['POST'])
# @login_required
def batch_delete_provider_models():
    """批量删除 ProviderModels"""
    data = request.get_json()
    ids = data.get('ids', [])
    if not ids:
        return jsonify({"message": "No IDs provided"}), 400

    try:
        ProviderModel.query.filter(ProviderModel.id.in_(ids)).delete(synchronize_session=False)
        db.session.commit()
        return jsonify({"message": f"Deleted {len(ids)} provider models"}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({"message": "Batch delete failed", "error": str(e)}), 500

# ---------- UserDefaultModel 模型的完整 CRUD 接口 ----------
@app.route('/user-default-models/<int:model_id>', methods=['GET'])
# @login_required
def get_user_default_model(model_id):
    """获取单个 UserDefaultModel 详情"""
    model = UserDefaultModel.query.get(model_id)
    if not model:
        return jsonify({"message": "User default model not found"}), 404
    return jsonify({
        'id': model.id,
        'user_id': model.user_id,
        'provider_name': model.provider_name,
        'model_name': model.model_name,
        'model_type': model.model_type,
        'created_at': model.created_at.isoformat(),
        'updated_at': model.updated_at.isoformat()
    }), 200

@app.route('/user-default-models', methods=['POST'])
# @login_required
def create_user_default_model():
    """创建 UserDefaultModel"""
    data = request.get_json()
    # 必填字段验证
    required_fields = ['provider_name', 'model_name', 'model_type']
    for field in required_fields:
        if not data.get(field):
            return jsonify({"message": f"Missing required field: {field}"}), 400

    # 创建记录
    new_model = UserDefaultModel(
        user_id=current_user.id,
        provider_name=data['provider_name'],
        model_name=data['model_name'],
        model_type=data['model_type']
    )
    db.session.add(new_model)
    db.session.commit()
    return jsonify({"message": "User default model created", "id": new_model.id}), 201

@app.route('/user-default-models/<int:model_id>', methods=['PUT'])
# @login_required
def update_user_default_model(model_id):
    """更新 UserDefaultModel"""
    model = UserDefaultModel.query.get(model_id)
    if not model:
        return jsonify({"message": "User default model not found"}), 404

    data = request.get_json()
    # 更新字段
    updatable_fields = ['provider_name', 'model_name', 'model_type']
    for field in updatable_fields:
        if field in data:
            setattr(model, field, data[field])

    db.session.commit()
    return jsonify({"message": "User default model updated"}), 200

@app.route('/user-default-models/<int:model_id>', methods=['DELETE'])
# @login_required
def delete_user_default_model(model_id):
    """删除单个 UserDefaultModel"""
    model = UserDefaultModel.query.get(model_id)
    if not model:
        return jsonify({"message": "User default model not found"}), 404

    db.session.delete(model)
    db.session.commit()
    return jsonify({"message": "User default model deleted"}), 200

@app.route('/user-default-models/batch-delete', methods=['POST'])
# @login_required
def batch_delete_user_default_models():
    """批量删除 UserDefaultModels"""
    data = request.get_json()
    ids = data.get('ids', [])
    if not ids:
        return jsonify({"message": "No IDs provided"}), 400

    try:
        UserDefaultModel.query.filter(UserDefaultModel.id.in_(ids)).delete(synchronize_session=False)
        db.session.commit()
        return jsonify({"message": f"Deleted {len(ids)} user default models"}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({"message": "Batch delete failed", "error": str(e)}), 500

# ---------- ProviderModelSetting 模型的完整 CRUD 接口 ----------
@app.route('/provider-model-settings/<int:setting_id>', methods=['GET'])
@login_required
def get_provider_model_setting(setting_id):
    """获取单个 ProviderModelSetting 详情"""
    setting = ProviderModelSetting.query.get(setting_id)
    if not setting:
        return jsonify({"message": "Provider model setting not found"}), 404
    return jsonify({
        'id': setting.id,
        'user_id': setting.user_id,
        'provider_name': setting.provider_name,
        'model_name': setting.model_name,
        'model_type': setting.model_type,
        'enabled': setting.enabled,
        'load_balancing_enabled': setting.load_balancing_enabled,
        'created_at': setting.created_at.isoformat(),
        'updated_at': setting.updated_at.isoformat()
    }), 200

@app.route('/provider-model-settings', methods=['POST'])
@login_required
def create_provider_model_setting():
    """创建 ProviderModelSetting"""
    data = request.get_json()
    # 必填字段验证
    required_fields = ['provider_name', 'model_name', 'model_type']
    for field in required_fields:
        if not data.get(field):
            return jsonify({"message": f"Missing required field: {field}"}), 400

    # 创建记录
    new_setting = ProviderModelSetting(
        user_id=current_user.id,
        provider_name=data['provider_name'],
        model_name=data['model_name'],
        model_type=data['model_type'],
        enabled=data.get('enabled', True),
        load_balancing_enabled=data.get('load_balancing_enabled', False)
    )
    db.session.add(new_setting)
    db.session.commit()
    return jsonify({"message": "Provider model setting created", "id": new_setting.id}), 201

@app.route('/provider-model-settings/<int:setting_id>', methods=['PUT'])
@login_required
def update_provider_model_setting(setting_id):
    """更新 ProviderModelSetting"""
    setting = ProviderModelSetting.query.get(setting_id)
    if not setting:
        return jsonify({"message": "Provider model setting not found"}), 404

    data = request.get_json()
    # 更新字段
    updatable_fields = ['provider_name', 'model_name', 'model_type', 'enabled', 'load_balancing_enabled']
    for field in updatable_fields:
        if field in data:
            setattr(setting, field, data[field])

    db.session.commit()
    return jsonify({"message": "Provider model setting updated"}), 200

@app.route('/provider-model-settings/<int:setting_id>', methods=['DELETE'])
@login_required
def delete_provider_model_setting(setting_id):
    """删除单个 ProviderModelSetting"""
    setting = ProviderModelSetting.query.get(setting_id)
    if not setting:
        return jsonify({"message": "Provider model setting not found"}), 404

    db.session.delete(setting)
    db.session.commit()
    return jsonify({"message": "Provider model setting deleted"}), 200

@app.route('/provider-model-settings/batch-delete', methods=['POST'])
@login_required
def batch_delete_provider_model_settings():
    """批量删除 ProviderModelSettings"""
    data = request.get_json()
    ids = data.get('ids', [])
    if not ids:
        return jsonify({"message": "No IDs provided"}), 400

    try:
        ProviderModelSetting.query.filter(ProviderModelSetting.id.in_(ids)).delete(synchronize_session=False)
        db.session.commit()
        return jsonify({"message": f"Deleted {len(ids)} provider model settings"}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({"message": "Batch delete failed", "error": str(e)}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5001, debug=False)